package com.xunwulian.web.controller.frame;

import com.alibaba.dubbo.config.annotation.Reference;
import com.google.common.collect.Lists;
import com.google.gson.Gson;
import com.xunwulian.api.dto.BaseResponse;
import com.xunwulian.api.iface.AppAPI;
import com.xunwulian.api.iface.RoleAPI;
import com.xunwulian.api.iface.UserAPI;
import com.xunwulian.base.constant.OperationType;
import com.xunwulian.base.entity.Page;
import com.xunwulian.base.entity.Role;
import com.xunwulian.base.entity.User;
import com.xunwulian.base.util.PageData;
import com.xunwulian.base.util.UserUtil;
import com.xunwulian.web.controller.BaseController;
import com.xunwulian.web.util.AppUtil;
import com.xunwulian.web.util.Const;
import com.xunwulian.web.util.JurisdictionHelper;
import com.xunwulian.web.util.PasswordUtil;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.crypto.hash.SimpleHash;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.propertyeditors.CustomDateEditor;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import java.io.PrintWriter;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;

@Controller
@RequestMapping(value = "/user")
public class UserController extends BaseController {

    String menuUrl = "user/list.do"; // 菜单地址(权限用)

    @Reference
    private UserAPI userAPI;
    @Reference
    private AppAPI appAPI;
    @Reference
    private RoleAPI roleAPI;

    private Gson gson = new Gson();

    /**
     * 获取用户列表
     *
     */
    @RequestMapping(value = "/list")
    public ModelAndView list(Page page, String userNameKey, String roleIdKey) {
        ModelAndView mv = this.getModelAndView();

        // 从session获取用户信息
        Subject currentUser = SecurityUtils.getSubject();
        Session session = currentUser.getSession();
        User user = (User) session.getAttribute(Const.SESSION_USER);

        // 管理员查询所有
        String userId = UserUtil.isAdmin(user.getROLE_ID()) || UserUtil.isSubAdmin(user.getROLE_ID()) ? "" : user.getUSER_ID();
        String appId = UserUtil.isSubAdmin(user.getROLE_ID()) ? user.getAppId() : "";

        BaseResponse<List<User>> response = userAPI.listPage(page, userNameKey, appId, userId);

        List<User> userList = response.getData();
        page = response.getPage();

        List<Role> roleList = roleAPI.getRoleList4Show(user.getROLE_ID());

        mv.setViewName("system/user/user_list");
        mv.addObject("userList", userList);
        mv.addObject("roleList", roleList);
        mv.addObject("userNameKey", userNameKey);
        mv.addObject("roleIdKey", roleIdKey);
        mv.addObject("page", page);

        mv.addObject(Const.SESSION_QX, this.getHC()); // 按钮权限
        return mv;
    }

    /**
     * 跳转到新增用户页面
     *
     */
    @RequestMapping(value = "/goAddU")
    public ModelAndView goAddU() {
        ModelAndView mv = this.getModelAndView();
        PageData pd = this.getPageData();

        // 从session获取用户信息
        Subject currentUser = SecurityUtils.getSubject();
        Session session = currentUser.getSession();
        User user = (User) session.getAttribute(Const.SESSION_USER);

        logger.info("pd:" + gson.toJson(pd));

        mv.addObject("msg", "saveU");
        mv.addObject("pd", pd);
        mv.addObject("roleList", roleAPI.getRoleList(user.getROLE_ID()));
        mv.addObject("appList", appAPI.list(user.getROLE_ID(), user.getAppId()));
        mv.setViewName("system/user/user_edit");

        return mv;
    }

    /**
     * 新增用户
     *
     */
    @RequestMapping(value = "/saveU")
    public ModelAndView saveU(PrintWriter out) {
        ModelAndView mv = this.getModelAndView();
        PageData pd = this.getPageData();

        // 从session获取用户信息
        Subject currentUser = SecurityUtils.getSubject();
        Session session = currentUser.getSession();
        User user = (User) session.getAttribute(Const.SESSION_USER);

        String userName = pd.getString("USERNAME");
        String name = pd.getString("NAME");
        String number = pd.getString("NUMBER");
        String phone = pd.getString("PHONE");
        String bz = pd.getString("BZ");
        String roleId = pd.getString("ROLE_ID");
        String email = pd.getString("EMAIL");
        String appId = pd.getString("APP_ID");

        User userEntity = new User();

        userEntity.setUSER_ID(this.get32UUID()); // ID
        userEntity.setRIGHTS("");
        userEntity.setLAST_LOGIN("");
        userEntity.setIP("");
        userEntity.setSTATUS("0");
        userEntity.setSkin("default");

        // 设置应用平台
        userEntity.setAppId(appId);

        userEntity.setCreator(user.getUSER_ID());

        userEntity.setUSERNAME(userName == null ? "" : userName);
        userEntity.setNAME(name == null ? "" : name);
        userEntity.setNumber(pd.getString("NUMBER") == null ? "" : number);
        userEntity.setPhone(phone == null ? "" : phone);
        userEntity.setBz(bz == null ? "" : bz);
        userEntity.setROLE_ID(roleId == null ? "" : roleId);
        userEntity.setEmail(email == null ? "" : email);

        logger.info("pd:" + gson.toJson(pd));
        String password = pd.getString("PASSWORD");

        userEntity.setPASSWORD(PasswordUtil.getPassword(userName, password));
        if (null == userAPI.getByName(userName)) {
            if (JurisdictionHelper.buttonJurisdiction(menuUrl, OperationType.ADD.role)) {
                userAPI.saveU(userEntity);
            }
            // 判断新增权限
            mv.addObject("msg", "success");
        } else {
            mv.addObject("msg", "failed");
        }
        mv.setViewName("save_result");
        return mv;
    }

    /**
     * 判断用户名是否存在
     *
     * @return
     */
    @RequestMapping(value = "/hasU")
    @ResponseBody
    public Object hasU() {
        Map<String, String> map = new HashMap<String, String>();
        String errInfo = "success";
        try {
            PageData pd  = this.getPageData();
            String userName = pd.getString("USERNAME");
            if (userAPI.getByName(userName) != null) {
                errInfo = "error";
            }
        } catch (Exception e) {
            logger.error(e.toString(), e);
        }
        map.put("result", errInfo); // 返回结果
        return AppUtil.returnObject(new PageData(), map);
    }

    /**
     * 判断邮箱是否存在
     *
     * @return
     */
    @RequestMapping(value = "/hasE")
    @ResponseBody
    public Object hasE() {
        Map<String, String> map = new HashMap<String, String>();
        String errInfo = "success";
        PageData pd = this.getPageData();
        try {
            String email = pd.getString("EMAIL");
            String userName = pd.getString("USERNAME");
            if (userAPI.getByNameAndEmail(email, userName) != null) {
                errInfo = "error";
            }
        } catch (Exception e) {
            logger.error(e.toString(), e);
        }
        map.put("result", errInfo); // 返回结果
        return AppUtil.returnObject(new PageData(), map);
    }

    /**
     * 判断编码是否存在
     *
     * @return
     */
    @RequestMapping(value = "/hasN")
    @ResponseBody
    public Object hasN() {
        Map<String, String> map = new HashMap<String, String>();
        String errInfo = "success";
        PageData pd = this.getPageData();
        try {
            String number = pd.getString("NUMBER");
            String userName = pd.getString("USERNAME");
            if (userAPI.getByNameAndNumber(number, userName) != null) {
                errInfo = "error";
            }
        } catch (Exception e) {
            logger.error(e.toString(), e);
        }
        map.put("result", errInfo); // 返回结果
        return AppUtil.returnObject(new PageData(), map);
    }


    /**
     * 跳转到修改用户页面
     *
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "/goEditU")
    public ModelAndView goEditU() {
        ModelAndView mv = this.getModelAndView();
        PageData pd = this.getPageData();

        // 从session获取用户信息
        Subject currentUser = SecurityUtils.getSubject();
        Session session = currentUser.getSession();
        User user = (User) session.getAttribute(Const.SESSION_USER);

        // 顶部修改个人资料
        String fx = pd.getString("fx");

        logger.info("去修改用户页面，" + fx);

        if ("head".equals(fx)) {
            mv.addObject("fx", "head");
        } else {
            mv.addObject("fx", "user");
        }

        // 列出可以创建的子角色
        List<Role> roleList = roleAPI.getRoleList(user.getROLE_ID());

        String editUserId = pd.getString("USER_ID");
        User editUser = userAPI.getByUid(editUserId);

        mv.setViewName("system/user/user_edit");
        mv.addObject("msg", "editU");
        mv.addObject("user", editUser);
        mv.addObject("roleList", roleList);

        List appList = appAPI.list(user.getROLE_ID(), user.getAppId());
        mv.addObject("appList", appList);

        return mv;
    }

    /**
     * 修改用户
     *
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "/editU")
    public ModelAndView editU() {
        ModelAndView mv = this.getModelAndView();
        PageData pd = this.getPageData();

        String password = pd.getString("PASSWORD");
        String userName = pd.getString("USERNAME");

        if (password != null && !"".equals(password)) {
            pd.put("PASSWORD", new SimpleHash("SHA-1", userName, password).toString());
        }

        if (JurisdictionHelper.buttonJurisdiction(menuUrl, OperationType.EDIT.role)) {
            User user = new User(pd.getString("USER_ID"),
                    pd.getString("USERNAME"),
                    pd.getString("PASSWORD"),
                    pd.getString("NAME"),
                    pd.getString("ROLE_ID"),
                    pd.getString("BZ"),
                    pd.getString("EMAIL"),
                    pd.getString("NUMBER"),
                    pd.getString("PHONE"));
            userAPI.editU(user);
        }

        mv.addObject("msg", "success");
        mv.setViewName("save_result");
        return mv;
    }


    /**
     * 删除用户
     *
     * @param out
     */
    @RequestMapping(value = "/deleteU")
    public void deleteU(PrintWriter out) {
        try {
            PageData pd = this.getPageData();
            if (JurisdictionHelper.buttonJurisdiction(menuUrl, OperationType.DEL.role)) {
                String userId = pd.getString("USER_ID");
                userAPI.deleteU(userId);
            }
            out.write("success");
            out.close();
        } catch (Exception e) {
            logger.error(e.toString(), e);
        }
    }

    /**
     * 批量删除
     *
     * @return
     */
    @RequestMapping(value = "/deleteAllU")
    @ResponseBody
    public Object deleteAllU() {
        PageData pd = new PageData();
        Map<String, Object> map = new HashMap<String, Object>();
        try {
            pd = this.getPageData();
            List<PageData> pdList = new ArrayList<PageData>();
            String USER_IDS = pd.getString("USER_IDS");
            if (null != USER_IDS && !"".equals(USER_IDS)) {
                List<String> idList = Lists.newArrayList(USER_IDS.split(","));
                if (JurisdictionHelper.buttonJurisdiction(menuUrl, OperationType.DEL.role)) {
                    userAPI.deleteAllU(idList);
                }
                pd.put("msg", "ok");
            } else {
                pd.put("msg", "no");
            }
            pdList.add(pd);
            map.put("list", pdList);
        } catch (Exception e) {
            logger.error(e.toString(), e);
        } finally {
            logAfter(logger);
        }
        return AppUtil.returnObject(pd, map);
    }

    /**
     * @param binder
     */
    @InitBinder
    public void initBinder(WebDataBinder binder) {
        DateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        binder.registerCustomEditor(Date.class, new CustomDateEditor(format,true));
    }

    /**
     * @return
     */
    public Map<String, String> getHC() {
        // shiro管理的session
        Subject currentUser = SecurityUtils.getSubject();
        Session session = currentUser.getSession();
        return (Map<String, String>) session.getAttribute(Const.SESSION_QX);
    }
}
